//package projects.part5;

import info.gridworld.grid.AbstractGrid;
import info.gridworld.grid.Location;

import java.util.ArrayList;

public class SparseBoundedGrid1a<E> extends AbstractGrid<E> {
    private SparseGridNode[] occArray;
    private int numCols;
    private int numRows;

    public SparseBoundedGrid1a(int rows, int cols){
        if (rows <= 0) {
            throw new IllegalArgumentException("Error! Rows <= 0");
        }
        if (cols <= 0) {
            throw new IllegalArgumentException("Error! Cols <= 0");
        }
        numRows = rows;
        numCols = cols;
        occArray = new SparseGridNode[rows];

    }

    @Override
    public int getNumRows() {
        return numRows;
    }

    @Override
    public int getNumCols() {
        return numCols;
    }

    @Override
    public boolean isValid(Location loc) {
        int c = loc.getCol();
        int r = loc.getRow();
        return 0 <= c && c < numCols && 0 <= r && r < numRows;
    }



    @Override
    // insert
    public E put(Location loc, E obj) {
        if (!isValid(loc))
            throw new IllegalArgumentException("Location " + loc
                    + " is not valid");
        if (obj == null)
            throw new NullPointerException("obj == null");

        // remove old
        E old = remove(loc);

        int r = loc.getRow();
        int c = loc.getCol();

        SparseGridNode p = occArray[r];
        // insert head
        occArray[r] = new SparseGridNode(obj,c,p);

        return  old;
    }

    @Override
    // overthrough
    public ArrayList<Location> getOccupiedLocations() {
        ArrayList<Location> res = new ArrayList<>();

        for (int r=0; r<getNumRows(); r++){
            SparseGridNode p = occArray[r];
            while (p!=null){
                Location tmp = new Location(r,p.getColumn());
                res.add(tmp);
                p = p.getNext();
            }
        }
        return res;
    }

    @Override
    // search
    public E get(Location loc) {
        //
        if (!isValid(loc)) {
            throw new IllegalArgumentException("Error! Location: " + loc + " is InValid.");
        }
        int r = loc.getRow();
        int c = loc.getCol();

        SparseGridNode p = occArray[r];
        while (p != null){
            if (c == p.getColumn())
                return (E)p.getOccupant();
            p = p.getNext();
        }
        return null;
    }

    @Override
    // delete
    public E remove(Location loc) {
        //
        if (!isValid(loc)) {
            throw new IllegalArgumentException("Error! Location: " + loc + " is InValid.");
        }

        E old = get(loc);
        if (old == null)    return null;

        int r = loc.getRow();
        int c = loc.getCol();

        SparseGridNode p = occArray[r];
        if (p != null){
            // if head
            if (p.getColumn() == c)
                occArray[r] = p.getNext();
            // if not head
            else {
                SparseGridNode q = p.getNext();
                while(q!=null && q.getColumn()!=c){
                    p = p.getNext();
                    q = q.getNext();
                }

                if (q !=null )
                    p.setNext(q.getNext());
            }
        }
        return old;
    }




}
